<?php
/**
 * Created by PhpStorm.
 * Script Name: Mpreply.php
 * Create: 2023/1/5 16:57
 * Description:
 * Author: fudaoji<fdj@kuryun.cn>
 */

namespace plugin\wechat\app\tenant\controller;

use app\common\constant\Common;
use app\common\model\App as AppM;
use app\common\model\TenantApp;
use app\common\service\Media as MediaService;
use app\common\service\Tenant as TenantService;
use app\common\service\Upload;
use plugin\wechat\app\service\Mp as MpService;
use plugin\wechat\app\model\MpMaterial as MaterialM;
use plugin\wechat\app\model\MpRule as RuleM;
use plugin\wechat\app\model\MpSpecial as SpecialM;
use plugin\wechat\app\TenantController;
use support\View;
use Support\Request;

class Mpreply extends TenantController
{
    /**
     * @var RuleM
     */
    protected $model;
    /**
     * @var SpecialM
     */
    protected $specialM;
    /**
     * @var Upload
     */
    private Upload $uploadService;

    public function __construct()
    {
        parent::__construct();
        $this->model = new RuleM();
        $this->specialM = new SpecialM();
        View::assign('config', dao_config('system.upload'));
        $this->uploadService = new Upload(dao_config('system.upload'));
    }

    public function savePost(Request $request, $jump = '', $data = [])
    {
        $mp_info = $request->mpInfo;
        if(request()->isPost()){
            $post_data = input('post.');
            $post_data['mp_id'] = $mp_info['id'];
            $post_data['company_id'] = TenantService::getCompanyId();
            if(empty($post_data[$this->pk])){
                $res = $this->validate($post_data,'\\plugin\\wechat\\app\\validate\\Rule.add');
            }else{
                $res = $this->validate($post_data,'\\plugin\\wechat\\app\\validate\\Rule.edit');
            }

            if($res !== true){
                return $this->error($res, '', ['token' => token()]);
            }
            $data = [
                'mp_id' => $post_data['mp_id'],
                'keyword' => $post_data['keyword'],
                'status' => $post_data['status'],
                'material_type' => $post_data['material_type'],
                'material_id' => $post_data['material_id']
            ];
            !empty($post_data[$this->pk]) && $data[$this->pk] = $post_data[$this->pk];
            return parent::savePost($request, '', $data);
        }
    }

    /**
     * 编辑关键词
     * @return mixed
     * Author: fudaoji<fdj@kuryun.cn>
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function edit(){
        $id = input('id');
        $data = $this->model->where([$this->tenantWhere()])->find($id);
        if(empty($data)){
            return $this->error('数据不存在');
        }

        if($data['material_type'] == MediaService::APP){
            $material = AppM::find($data['material_id']);
        }else{
            $material = MaterialM::where([$this->tenantWhere()])
                ->find($data['material_id']);
            if($data['material_type'] == MediaService::NEWS){
                $material['children'] = MaterialM::where([$this->tenantWhere(), ['pid', '=', $material['id']]])
                    ->field(['thumb_url', 'title'])
                   ->order(['index' => 'asc'])
                    ->select();
            }
        }

        $builder = new FormBuilder();
        $builder->setPostUrl(url('savePost'))
            ->addFormItem('id', 'hidden', 'ID', 'ID', [], 'required')
            ->addFormItem('keyword', 'text', '关键词', '不超过40字', [], 'required maxlength=40')
            ->addFormItem('status', 'radio', '是否开启', '是否开启', [1 => '是', 0 => '否'], 'required')
            ->addFormItem('material', 'choose_wx_media', '回复类型', '回复类型', ['types' => MpService::replyTypes(), 'id' => $data['material_id'], 'type' => $data['material_type']], 'required')
            ->setFormData($data);
        return $builder->show(['material' => $material]);
    }

    /**
     * 新增关键词
     * @return mixed
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function add(){
        $builder = new FormBuilder();
        $builder->setPostUrl(url('savePost'))
            ->addFormItem('keyword', 'text', '关键词', '不超过40字', [], 'required maxlength=40')
            ->addFormItem('status', 'radio', '是否开启', '是否开启', [1 => '是', 0 => '否'], 'required')
            ->addFormItem('material', 'choose_wx_media', '回复类型', '回复类型', ['types' => MpService::replyTypes()], 'required')
            ->setFormData(['status' => 1]);
        return $builder->show();
    }

    /**
     * 回复列表
     * @param Request $request
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function index(Request $request)
    {
        $mp_info = $request->mpInfo;
        $type = input('type', MediaService::TEXT);

        if(request()->isPost()){
            $post_data = input('post.');
            $where = [
                $this->tenantWhere('rule'),
                ['rule.mp_id', '=', $mp_info['id']],
                ['material_type', '=', $type]
            ];

            if($search_key = input('keyword', '')){
                $where[] = ['keyword', 'like', '%'.$search_key.'%'];
            }

            switch ($type) {
                case 'text':
                case 'news':
                case 'voice':
                case 'image':
                case 'video':
                case 'music':
                case 'link':
                    $query = $this->model->alias('rule')
                        ->join($request->plugin . '_mp_material material', 'material.id=rule.material_id')
                        ->field(['material.*', 'rule.keyword', 'rule.id', 'rule.status']);
                    break;
                default:
                    $query = $this->model->alias('rule')
                        ->join('app app', 'app.id=rule.material_id')
                        ->field(['app.*', 'rule.keyword', 'rule.id', 'rule.status']);
                    break;
            }

            $query = $query->where($where);
            $total = $query->count();
            if ($total) {
                $list = $query->page($post_data['page'], $post_data['limit'])
                    ->order('rule.id', 'desc')
                    ->select();
            } else {
                $list = [];
            }

            return $this->success('success', '', ['total' => $total, 'list' => $list]);
        }

        $builder = new ListBuilder();
        $builder->setSearch([
            ['type' => 'text', 'name' => 'search_key', 'title' => '搜索词','placeholder' => '输入关键词']
        ])
            ->setTabNav($this->tabList(), $type)
            ->addTopButton('addnew')
            ->addTopButton('addnew', ['class' => '','href' => url('special'), 'text' => '特殊消息/事件', 'title' => '特殊消息/事件'])
            ->addTableColumn(['title' => '关键词', 'field' => 'keyword', 'minWidth' => 100]);
        switch ($type) {
            case 'text':
                $builder->addTableColumn(['title' => '回复内容', 'field' => 'content', 'minWidth' => 100]);
                break;
            case 'image':
                $builder->addTableColumn(['title' => '图片', 'field' => 'server_url', 'type' => 'picture', 'minWidth' => 100]);
                break;
            case 'news':
                $builder->addTableColumn(['title' => '标题', 'field' => 'title', 'minWidth' => 100])
                    ->addTableColumn(['title' => '封面图', 'field' => 'thumb_url', 'type' => 'picture', 'minWidth' => 100])
                    ->addTableColumn(['title' => '摘要', 'field' => 'digest', 'minWidth' => 150]);
                break;
            case 'voice':
                $builder->addTableColumn(['title' => '文件名称', 'field' => 'title', 'minWidth' => 100])
                    ->addTableColumn(['title' => '试听', 'field' => 'server_url', 'type' => 'voice', 'minWidth' => 200]);
                break;
            case 'video':
                $builder->addTableColumn(['title' => '文件名称', 'field' => 'title', 'minWidth' => 100])
                    ->addTableColumn(['title' => '试看', 'field' => 'server_url', 'type' => 'video', 'minWidth' => 200]);
                break;
            case 'music':
                $builder->addTableColumn(['title' => '名称', 'field' => 'title', 'minWidth' => 100])
                    ->addTableColumn(['title' => '试听', 'field' => 'server_url', 'type' => 'voice', 'minWidth' => 200])
                    ->addTableColumn(['title' => '音乐描述', 'field' => 'digest', 'minWidth' => 150]);
                break;
            case 'link':
                $builder->addTableColumn(['title' => '标题', 'field' => 'title', 'minWidth' => 100])
                    ->addTableColumn(['title' => '描述', 'field' => 'digest', 'minWidth' => 200])
                    ->addTableColumn(['title' => '封面', 'field' => 'thumb_url', 'minWidth' => 100, "type" => 'picture'])
                    ->addTableColumn(['title' => '跳转链接', 'field' => 'source_url', 'minWidth' => 200]);
                break;
            default:
                $builder->addTableColumn(['title' => '应用', 'field' => 'title', 'minWidth' => 100])
                    ->addTableColumn(['title' => 'logo', 'field' => 'logo', 'type' => 'picture', 'minWidth' => 100])
                    ->addTableColumn(['title' => '简介', 'field' => 'desc', 'minWidth' => 150]);
                break;
        }
        $builder->addTableColumn(['title' => '状态', 'field' => 'status', 'type' => 'switch', 'options' => Common::status()])
            ->addTableColumn(['title' => '操作', 'minWidth' => 120, 'type' => 'toolbar'])
            ->addRightButton('edit')
            ->addRightButton('delete');
        return $builder->show();
    }

    private function tabList(){
        $types = MpService::replyTypes();
        $list = [];
        foreach ($types as $key => $type){
            $list[$key] = ['title' => $type, 'href' => url('index', ['type' => $key])];
        }
        return $list;
    }

    /**
     * 特殊消息/事件
     * @param Request $request
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function special(Request $request){
        $mp_info = $request->mpInfo;
        $events = MpService::specialEvents();
        if(request()->isPost()){
            $post_data = input('post.');
            foreach ($events as $k => $event){
                $special = $this->specialM->where([
                    $this->tenantWhere(),
                    ['event', '=', $k],
                    ['mp_id', '=', $mp_info['id']]
                ])->find();
                $update_data = [
                    'id' => $special['id'],
                    'keyword' => '',
                    'app_name' => '',
                    'status' => 1
                ];
                $dict = [
                    'status' => 0,
                    'keyword' => $post_data[$k . '_keyword'],
                    'app_name' => $post_data[$k . '_app']
                ];
                $update_data[$post_data[$k]] = $dict[$post_data[$k]];
                $this->specialM->update($update_data);
            }
            return $this->success('操作成功!');
        }

        $replies = $this->specialM->where([
            $this->tenantWhere(),
            ['mp_id' ,'=', $mp_info['id']],
        ])->select();
        if(!count($replies)){
            $insert_data = [];
            foreach ($events as $k => $event){
                $insert_data[] = [
                    'event' => $k,
                    'mp_id' => $mp_info['id'],
                    'company_id' => $mp_info['company_id'],
                    'status' => 0
                ];
            }
            $this->specialM->saveAll($insert_data);
            $replies = $this->specialM->where([
                $this->tenantWhere(),
                ['mp_id' ,'=', $mp_info['id']],
            ])->select();
        }

        $apps = TenantApp::alias('ta')
            ->join('app app', 'app.name=ta.app_name')
            ->where([
                $this->tenantWhere('ta'),
                ['app.status', '=', 1],
                ['ta.status', '=', 1],
                ['ta.deadline', '>', time()],
        ])
            ->field(['app.id','app.name', 'app.title'])
        ->order('ta.id', 'desc')
        ->select();

        $assign = [
            'replies' => $replies,
            'events' => $events,
            'apps' => $apps
        ];
        return $this->show($assign);
    }
}